package crm.util;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import crm.dbcoon.DBConnect;

/**
 * 
 * @author BOY_CHN 创建日期:2007-5-28 下午01:13:41 <br>
 * 实现了同时分页查询和分页目录显示的功能
 * 
 * @version 
 * 		2.0
 * 
 * @since
 * 		1.0
 */
public abstract class Pagination {

	/** 查询语句 */
	private String sql;

	/** 每页的记录数 */
	private int rowsPerPage;

	/** 总的记录数 */
	private int rowsCount;

	/** 总的页数 */
	private int pagesCount;

	/**
	 * 本类的唯一构造方法
	 * 
	 * @param sql
	 *            欲传入的SQL语句
	 * @param rowsPerPage
	 *            设置每页显示的记录数
	 */
	public Pagination(String sql, int rowsPerPage,int flag) {
		// 设置当前的查询语句
		setRowsPerPage(rowsPerPage);
		setSql(sql,flag);
	}

	/**
	 * 设置每页显示的记录数
	 * 
	 * @param 要设置的每页显示的记录数
	 *            <br>
	 *            当要显示的记录数大于0时，接受参数的值<br>
	 *            否则设为默认(20)
	 * 
	 */
	public void setRowsPerPage(int rowsPerPage) {
		if (rowsPerPage > 0)
			this.rowsPerPage = rowsPerPage;
		else
			this.rowsPerPage = 20;
	}

	/**
	 * 返回总的页数
	 * 
	 * @return the pagesCount
	 */
	public int getPagesCount() {
		return pagesCount;
	}

	/**
	 * 返回总的记录数
	 * 
	 * @return the rowsCount
	 */
	public int getRowsCount() {
		return rowsCount;
	}

	/**
	 * @return the rowsPerPage
	 */
	public int getRowsPerPage() {
		return rowsPerPage;
	}

	/**
	 * 设置原始的SQL
	 * 
	 * @param sql
	 *            the sql to set
	 */
	private void setSql(String sql,int flag) {
		this.sql = sql;
		this.rowsCount = 0;
		this.pagesCount = 0;

		// 获取总行数并计算总页数
		this.rowsCount = countRows(flag);
		this.pagesCount = countPage();
	}

	/**
	 * 返回指定页号的记录集---记录集为集合类的方式<br />
	 * 集成了简单的错误处理功能-当用户给定的页码小于0的时候，返回第一页 当用户给定的页面大于最大的页面的时候，返回最后一页
	 * 
	 * @param page
	 *            当前的页数
	 * @return Collection
	 */
	@SuppressWarnings("unchecked")
	public Collection<Object> getPage(int page) throws SQLException,Exception {

		Collection<Object> result = new ArrayList<Object>();

		if (countPage() == 0) {
			return Collections.EMPTY_LIST;
		}

		DBConnect dbc = new DBConnect();
		ResultSet rs = null;

		// 判断用户给Page属性是否合法
		if (page <= 0)
			page = 1;
		if (page > pagesCount)
			page = pagesCount;

		// 根据页号计算起始行
		int startRow = (page - 1) * getRowsPerPage() + 1;
		int rows = this.getRowsPerPage();

		// 将SQL语句转换为特定数据库的定位行集SQL语句
		String pageSQl = MySqlPageSQL.getPageSQL(this.sql, startRow, rows);

		dbc.prepareStatement(pageSQl);

		try {
			rs = dbc.executeQuery();
			result = packResultSet(rs);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbc.close(rs);
			dbc.close();
		}
		return result;
	}
	/**
	 * 返回指定页号的记录集---记录集为集合类的方式<br />
	 * 集成了简单的错误处理功能-当用户给定的页码小于0的时候，返回第一页 当用户给定的页面大于最大的页面的时候，返回最后一页
	 * 
	 * @param page
	 *            当前的页数
	 * @return Collection
	 */
	@SuppressWarnings("unchecked")
	public Collection<Object> getPage1(int page) {

		Collection<Object> result = new ArrayList<Object>();

		if (countPage() == 0) {
			return Collections.EMPTY_LIST;
		}

		DBConnect dbc = new DBConnect();
		ResultSet rs = null;

		// 判断用户给Page属性是否合法
		if (page <= 0)
			page = 1;
		if (page > pagesCount)
			page = pagesCount;

		// 根据页号计算起始行
		int startRow = (page - 1) * getRowsPerPage() + 1;
		int rows = this.getRowsPerPage();

		// 将SQL语句转换为特定数据库的定位行集SQL语句
		String pageSQl = MySqlPageSQL.getPageSQL(this.sql, startRow, rows);

		dbc.prepareStatement(pageSQl);

		try {
			rs = dbc.executeQuery();
			result = packResultSet(dbc,rs);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbc.close(rs);
			dbc.close();
		}
		return result;
	}
	/**
	 * 计算这个数据表中有多少条数据
	 * 
	 * @return 数据表中的记录数
	 */
	private int countRows(int flag) {
		int count = 0;
		String countSql = this.sql;
		String temp = countSql;
		countSql = countSql.toLowerCase();
		int fromPos = countSql.indexOf("from");
		countSql = countSql.substring(fromPos);
		if(flag==1){
			countSql = "select count(*)" + countSql;
		}
		else if(flag==2){
		    countSql = "select count(distinct(info_student.id))" + countSql;
		}
		else if(flag==3){
			countSql = "select count(*) from (" + temp +") as aa";
		}
		// System.out.println(countSql);
		DBConnect dbc = new DBConnect(countSql);
		ResultSet rs = null;

		try {
			rs = dbc.executeQuery();
			rs.first();
			count = rs.getInt(1);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbc.close(rs);
			dbc.close();
		}
		return count;
	}

	/**
	 * 计算总的页数
	 * 
	 * @return 总页数
	 */
	private int countPage() {
		if (rowsCount % rowsPerPage == 0)
			return rowsCount / rowsPerPage;
		else
			return (rowsCount / rowsPerPage + 1);
	}

	/**
	 * 包装记录集(ResultSet) 的抽象方法
	 * 
	 * @param rs
	 *            欲包装的记录集
	 * @return 返回含有记录集对应表的实体的集合类
	 */
	protected abstract Collection packResultSet(ResultSet rs) throws SQLException;
	protected Collection packResultSet(DBConnect dbc,ResultSet rs) throws SQLException{
		return Collections.EMPTY_LIST;
	}
	
	/**
	 * 显示用的菜单
	 * 
	 * @param page
	 *            当前的页码
	 * @return 要显示菜单的HTML代码
	 */
	public String getToolsMenu(int page) {
		StringBuilder str = new StringBuilder("");

		int next, prev;
		prev = page - 1;
		next = page + 1;

		if (page > 1) {
			str.append("<a href=\"#\" onclick=\"javascript:document.forms[1].pages.value=1;document.forms[1].submit();\">首页</a> ");
		} else {
			str.append("<a href=\"#\">首页</a> ");
		}
		if (page > 1) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + prev
					+ ";document.forms[1].submit();'>上页</a> ");
		} else {
			str.append("<a href=\"#\">上页</a> ");
		}
		if (page < pagesCount) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + next
					+ ";document.forms[1].submit();'>下页</a> ");
		} else {
			str.append("<a href=\"#\" >下页</a> ");
		}
		if (pagesCount > 1 && page != pagesCount) {
			str.append("<a href=\"#\"  onclick='javascript:document.forms[1].pages.value=" + pagesCount
					+ ";document.forms[1].submit();'>末页</a>  ");
		} else {
			str.append("<a href=\"#\" >末页</a>  ");
		}
		str.append(" 共" + rowsCount + "条记录");

		str.append("  每页<SELECT size=1 name=pagesize onchange='javascript:this.form.pages.value=1;this.form.pageSize.value=this.value;this.form.submit();'>");

		if (rowsPerPage == 10) {
			str.append("<OPTION value=10 selected>10</OPTION>");
		} else {
			str.append("<OPTION value=10>10</OPTION>");
		}
		if (rowsPerPage == 20) {
			str.append("<OPTION value=20 selected>20</OPTION>");
		} else {
			str.append("<OPTION value=20>20</OPTION>");
		}
		if (rowsPerPage == 50) {
			str.append("<OPTION value=50 selected>50</OPTION>");
		} else {
			str.append("<OPTION value=50>50</OPTION>");
		}
		if (rowsPerPage == 100) {
			str.append("<OPTION value=100 selected>100</OPTION>");
		} else {
			str.append("<OPTION value=100>100</OPTION>");
		}
		str.append("</SELECT>");

		str.append("条 分" + pagesCount + "页显示 转到");
		str.append("<SELECT size=1 name=Pagelist onchange='javascript:this.form.pages.value=this.value;this.form.submit();'>");
		for (int i = 1; i < pagesCount + 1; i++) {
			if (i == page) {
				str.append("<OPTION value=" + i + " selected>" + i + "</OPTION>");
			} else {
				str.append("<OPTION value=" + i + ">" + i + "</OPTION>");
			}
		}
		str.append("</SELECT>页");
		str.append("<form><INPUT type=hidden  value=" + page + " name=\"pages\" >");
		str.append("<INPUT type=hidden  value=" + rowsPerPage + " name=\"pageSize\">  </form>");

		return str.toString();
	}	
	/**
	 * 显示用的菜单
	 * 
	 * @param page
	 *            当前的页码
	 * @return 要显示菜单的HTML代码
	 */
	public String getToolsMenu_1(int page,String type,String key) {
		StringBuilder str = new StringBuilder("");

		int next, prev;
		prev = page - 1;
		next = page + 1;

		if (page > 1) {
			str.append("<a href=\"#\" onclick=\"javascript:document.forms[1].pages.value=1;document.forms[1].submit();\">首页</a> ");
		} else {
			str.append("<a href=\"#\">首页</a> ");
		}
		if (page > 1) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + prev
					+ ";document.forms[1].submit();'>上页</a> ");
		} else {
			str.append("<a href=\"#\">上页</a> ");
		}
		if (page < pagesCount) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + next
					+ ";document.forms[1].submit();'>下页</a> ");
		} else {
			str.append("<a href=\"#\" >下页</a> ");
		}
		if (pagesCount > 1 && page != pagesCount) {
			str.append("<a href=\"#\"  onclick='javascript:document.forms[1].pages.value=" + pagesCount
					+ ";document.forms[1].submit();'>末页</a>  ");
		} else {
			str.append("<a href=\"#\" >末页</a>  ");
		}
		str.append(" 共" + rowsCount + "条记录");

		str.append("  每页<SELECT size=1 name=pagesize onchange='javascript:this.form.pages.value=1;this.form.pageSize.value=this.value;this.form.submit();'>");

		if (rowsPerPage == 10) {
			str.append("<OPTION value=10 selected>10</OPTION>");
		} else {
			str.append("<OPTION value=10>10</OPTION>");
		}
		if (rowsPerPage == 20) {
			str.append("<OPTION value=20 selected>20</OPTION>");
		} else {
			str.append("<OPTION value=20>20</OPTION>");
		}
		if (rowsPerPage == 50) {
			str.append("<OPTION value=50 selected>50</OPTION>");
		} else {
			str.append("<OPTION value=50>50</OPTION>");
		}
		if (rowsPerPage == 100) {
			str.append("<OPTION value=100 selected>100</OPTION>");
		} else {
			str.append("<OPTION value=100>100</OPTION>");
		}
		str.append("</SELECT>");

		str.append("条 分" + pagesCount + "页显示 转到");
		str.append("<SELECT size=1 name=Pagelist onchange='javascript:this.form.pages.value=this.value;this.form.submit();'>");
		for (int i = 1; i < pagesCount + 1; i++) {
			if (i == page) {
				str.append("<OPTION value=" + i + " selected>" + i + "</OPTION>");
			} else {
				str.append("<OPTION value=" + i + ">" + i + "</OPTION>");
			}
		}
		str.append("</SELECT>页");
		str.append("<form ><INPUT type=hidden  value=" + page + " name=\"pages\" >");
		str.append("<INPUT type=hidden  value=" + type + " name=\"m_type\" >");
		str.append("<INPUT type=hidden  value=" + key + " name=\"m_key\" >");
		str.append("<INPUT type=hidden  value=" + rowsPerPage + " name=\"pageSize\">  </form>");

		return str.toString();
	}	
	/**
	 * 显示用的菜单
	 * 
	 * @param page
	 *            当前的页码
	 * @return 要显示菜单的HTML代码
	 */
	public String getToolsMenu_2(int page,String sort_field) {
		StringBuilder str = new StringBuilder("");

		int next, prev;
		prev = page - 1;
		next = page + 1;

		if (page > 1) {
			str.append("<a href=\"#\" onclick=\"javascript:document.forms[1].pages.value=1;document.forms[1].submit();\">首页</a> ");
		} else {
			str.append("<a href=\"#\">首页</a> ");
		}
		if (page > 1) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + prev
					+ ";document.forms[1].submit();'>上页</a> ");
		} else {
			str.append("<a href=\"#\">上页</a> ");
		}
		if (page < pagesCount) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + next
					+ ";document.forms[1].submit();'>下页</a> ");
		} else {
			str.append("<a href=\"#\" >下页</a> ");
		}
		if (pagesCount > 1 && page != pagesCount) {
			str.append("<a href=\"#\"  onclick='javascript:document.forms[1].pages.value=" + pagesCount
					+ ";document.forms[1].submit();'>末页</a>  ");
		} else {
			str.append("<a href=\"#\" >末页</a>  ");
		}
		str.append(" 共" + rowsCount + "条记录");

		str.append("  每页<SELECT size=1 name=pagesize onchange='javascript:this.form.pages.value=1;this.form.pageSize.value=this.value;this.form.submit();'>");

		if (rowsPerPage == 10) {
			str.append("<OPTION value=10 selected>10</OPTION>");
		} else {
			str.append("<OPTION value=10>10</OPTION>");
		}
		if (rowsPerPage == 20) {
			str.append("<OPTION value=20 selected>20</OPTION>");
		} else {
			str.append("<OPTION value=20>20</OPTION>");
		}
		if (rowsPerPage == 50) {
			str.append("<OPTION value=50 selected>50</OPTION>");
		} else {
			str.append("<OPTION value=50>50</OPTION>");
		}
		if (rowsPerPage == 100) {
			str.append("<OPTION value=100 selected>100</OPTION>");
		} else {
			str.append("<OPTION value=100>100</OPTION>");
		}
		str.append("</SELECT>");

		str.append("条 分" + pagesCount + "页显示 转到");
		str.append("<SELECT size=1 name=Pagelist onchange='javascript:this.form.pages.value=this.value;this.form.submit();'>");
		for (int i = 1; i < pagesCount + 1; i++) {
			if (i == page) {
				str.append("<OPTION value=" + i + " selected>" + i + "</OPTION>");
			} else {
				str.append("<OPTION value=" + i + ">" + i + "</OPTION>");
			}
		}
		str.append("</SELECT>页");
		str.append("<form ><INPUT type=hidden  value=" + page + " name=\"pages\" >");
		str.append("<INPUT type=hidden  value=" + sort_field + " name=\"sort_field\" >");
		str.append("<INPUT type=hidden  value=" + rowsPerPage + " name=\"pageSize\">  </form>");

		return str.toString();
	}	
	/**
	 * 显示用的菜单
	 * 
	 * @param page
	 *            当前的页码
	 * @return 要显示菜单的HTML代码
	 */
	public String getToolsMenu_2(int page,String sort_field_1,String sort_field_2) {
		StringBuilder str = new StringBuilder("");

		int next, prev;
		prev = page - 1;
		next = page + 1;

		if (page > 1) {
			str.append("<a href=\"#\" onclick=\"javascript:document.forms[1].pages.value=1;document.forms[1].submit();\">首页</a> ");
		} else {
			str.append("<a href=\"#\">首页</a> ");
		}
		if (page > 1) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + prev
					+ ";document.forms[1].submit();'>上页</a> ");
		} else {
			str.append("<a href=\"#\">上页</a> ");
		}
		if (page < pagesCount) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + next
					+ ";document.forms[1].submit();'>下页</a> ");
		} else {
			str.append("<a href=\"#\" >下页</a> ");
		}
		if (pagesCount > 1 && page != pagesCount) {
			str.append("<a href=\"#\"  onclick='javascript:document.forms[1].pages.value=" + pagesCount
					+ ";document.forms[1].submit();'>末页</a>  ");
		} else {
			str.append("<a href=\"#\" >末页</a>  ");
		}
		str.append(" 共" + rowsCount + "条记录");

		str.append("  每页<SELECT size=1 name=pagesize onchange='javascript:this.form.pages.value=1;this.form.pageSize.value=this.value;this.form.submit();'>");

		if (rowsPerPage == 10) {
			str.append("<OPTION value=10 selected>10</OPTION>");
		} else {
			str.append("<OPTION value=10>10</OPTION>");
		}
		if (rowsPerPage == 20) {
			str.append("<OPTION value=20 selected>20</OPTION>");
		} else {
			str.append("<OPTION value=20>20</OPTION>");
		}
		if (rowsPerPage == 50) {
			str.append("<OPTION value=50 selected>50</OPTION>");
		} else {
			str.append("<OPTION value=50>50</OPTION>");
		}
		if (rowsPerPage == 100) {
			str.append("<OPTION value=100 selected>100</OPTION>");
		} else {
			str.append("<OPTION value=100>100</OPTION>");
		}
		str.append("</SELECT>");

		str.append("条 分" + pagesCount + "页显示 转到");
		str.append("<SELECT size=1 name=Pagelist onchange='javascript:this.form.pages.value=this.value;this.form.submit();'>");
		for (int i = 1; i < pagesCount + 1; i++) {
			if (i == page) {
				str.append("<OPTION value=" + i + " selected>" + i + "</OPTION>");
			} else {
				str.append("<OPTION value=" + i + ">" + i + "</OPTION>");
			}
		}
		str.append("</SELECT>页");
		str.append("<form ><INPUT type=hidden  value=" + page + " name=\"pages\" >");
		str.append("<INPUT type=hidden  value=" + sort_field_1 + " name=\"sort_field_1\" >");
		str.append("<INPUT type=hidden  value=" + sort_field_2 + " name=\"sort_field_2\" >");
		str.append("<INPUT type=hidden  value=" + rowsPerPage + " name=\"pageSize\">  </form>");

		return str.toString();
	}	
	/**
	 * 显示用的菜单
	 * 
	 * @param page
	 *            当前的页码
	 * @return 要显示菜单的HTML代码
	 */
	public String getUserToolsMenu(int page) {
		StringBuilder str = new StringBuilder("");

		int next, prev;
		prev = page - 1;
		next = page + 1;

		if (page > 1) {
			str.append("<a href=\"#\" onclick=\"javascript:document.forms[1].pages.value=1;document.forms[1].submit();\">首页</a> ");
		} else {
			str.append("<a href=\"#\">首页</a> ");
		}
		if (page > 1) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + prev
					+ ";document.forms[1].submit();'>上页</a> ");
		} else {
			str.append("<a href=\"#\">上页</a> ");
		}
		if (page < pagesCount) {
			str.append("<a href=\"#\" onclick='javascript:document.forms[1].pages.value=" + next
					+ ";document.forms[1].submit();'>下页</a> ");
		} else {
			str.append("<a href=\"#\" >下页</a> ");
		}
		if (pagesCount > 1 && page != pagesCount) {
			str.append("<a href=\"#\"  onclick='javascript:document.forms[1].pages.value=" + pagesCount
					+ ";document.forms[1].submit();'>末页</a>  ");
		} else {
			str.append("<a href=\"#\" >末页</a>  ");
		}
		str.append(" 共" + rowsCount + "条记录");

		str.append("  每页<SELECT size=1 name=pagesize onchange='javascript:this.form.pages.value=1;this.form.pageSize.value=this.value;this.form.submit();'>");

		if (rowsPerPage == 10) {
			str.append("<OPTION value=10 selected>10</OPTION>");
		} else {
			str.append("<OPTION value=10>10</OPTION>");
		}
		if (rowsPerPage == 20) {
			str.append("<OPTION value=20 selected>20</OPTION>");
		} else {
			str.append("<OPTION value=20>20</OPTION>");
		}
		if (rowsPerPage == 50) {
			str.append("<OPTION value=50 selected>50</OPTION>");
		} else {
			str.append("<OPTION value=50>50</OPTION>");
		}
		if (rowsPerPage == 100) {
			str.append("<OPTION value=100 selected>100</OPTION>");
		} else {
			str.append("<OPTION value=100>100</OPTION>");
		}
		str.append("</SELECT>");

		str.append("条 分" + pagesCount + "页显示 转到");
		str.append("<SELECT size=1 name=Pagelist onchange='javascript:this.form.pages.value=this.value;this.form.submit();'>");
		for (int i = 1; i < pagesCount + 1; i++) {
			if (i == page) {
				str.append("<OPTION value=" + i + " selected>" + i + "</OPTION>");
			} else {
				str.append("<OPTION value=" + i + ">" + i + "</OPTION>");
			}
		}
		str.append("</SELECT>页");
		str.append("<form><INPUT type=hidden  value=" + page + " name=\"pages\" >");
		str.append("<INPUT type=hidden  value=" + rowsPerPage + " name=\"pageSize\">  </form>");

		return str.toString();
	}
	
}
